home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / computerjanitorapp / terminalsize.py < prev    next >
Encoding:
Python Source  |  2009-03-04  |  2.7 KB  |  70 lines

  1. # terminalsize.py - find size of terminal
  2. # Copyright (C) 2008  Canonical, Ltd.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, version 3 of the License.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  15.  
  16. # Inspired by code by Chuck Blake, at
  17. # http://pdos.csail.mit.edu/~cblake/cls/cls.py, but rewritten in an
  18. # attempt to clarify things. This code is slightly tricky, so I thought
  19. # the extra clarity would be worth it.
  20.  
  21. import fcntl
  22. import os
  23. import struct
  24. import termios
  25.  
  26.  
  27. def get_terminal_size(fd=1):
  28.     """Return size of terminal attached to the standard output.
  29.     
  30.     Use ioctl(2) to query a terminal for its size, given a file
  31.     descriptor attached to the terminal. Return (None, None) if this
  32.     fails, otherwise a tuple (columns, rows).
  33.     
  34.     (The optional 'fd' argument can be set to whatever file
  35.     descriptor you want to use. This is useful for unit tests.)
  36.     
  37.     """
  38.  
  39.     try:
  40.         # Do the ioctl call. termios.TIOCGWINSZ is the code to query
  41.         # terminal size (see tty_ioctl(4), at least on Linux). We need
  42.         # to give it a string of suitable size to use as the input
  43.         # buffer for ioctl. Ioctl modifies the buffer and returns the
  44.         # modified buffer as its return value.
  45.         #
  46.         # The manual page specifies a struct winsize to be used, which
  47.         # consists of four unsigned shorts. We use struct.calcsize to
  48.         # compute the size of that.
  49.         # 
  50.         # Note that Blake's original code assumes only the first two 
  51.         # shorts in the struct are used, and that two shorts fit into
  52.         # four bytes, which is probably true for all the relevant
  53.         # platforms, but is cramped enough that it makes me feel icky.
  54.         # Thus, I assume less. This will still break if the contents
  55.         # of the struct change, but since that would change the system
  56.         # call API, that's unlikely.
  57.         
  58.         buflen = struct.calcsize('hhhh')
  59.         buf = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * buflen)
  60.         
  61.         # ioctl returns a binary buffer that represents the struct
  62.         # at the C level. We unpack it with struct.unpack.
  63.         
  64.         tuple = struct.unpack('hhhh', buf)
  65.     except:
  66.         # If anything went wrong, we give up and claim we don't know.
  67.         return None, None
  68.  
  69.     return tuple[0], tuple[1]
  70.